﻿using System;
using System.Linq;
using System.Security.Principal;

namespace CLK.AspNet.Identity
{
    /// <summary>
    /// 权限 授权
    /// </summary>
    public abstract class PermissionAuthorize
    {
        // Constructors
        internal PermissionAuthorize()
        {
        }

        /// <summary>
        /// 判断当前用户是否有此权限
        /// </summary>
        /// <param name="user">用户</param>
        /// <param name="permissionName">权限名</param>
        /// <returns></returns>
        public abstract bool Authorize(IPrincipal user, string permissionName);
    }

    public class PermissionAuthorize<TPermission, TKey> : PermissionAuthorize
        where TPermission : class, CLK.AspNet.Identity.IPermission<TKey>
        where TKey : IEquatable<TKey>
    {
        #region 注入

        // Fields
        private PermissionManager<TPermission, TKey> _permissionManager = null;

        // Constructors
        public PermissionAuthorize(PermissionManager<TPermission, TKey> permissionManager)
        {
            #region Contracts

            if (permissionManager == null) throw new ArgumentNullException("permissionManager");

            #endregion Contracts

            // Default
            _permissionManager = permissionManager;
        }

        #endregion 注入

        /// <summary>
        /// 判断当前用户是否有此权限
        /// </summary>
        /// <param name="user">用户</param>
        /// <param name="permissionName">权限名</param>
        /// <returns>用户有此权限返回true，否则返回false</returns>
        public override bool Authorize(IPrincipal user, string permissionName = null)
        {
            #region Contracts

            if (user == null) throw new ArgumentNullException("user");

            #endregion Contracts

            // Require
            if (user.Identity.IsAuthenticated == false) return false;
            if (string.IsNullOrEmpty(permissionName) == true) return true;

            // PermissionRoles
            var permissionRoles = _permissionManager.GetRolesByName(permissionName);
            if (permissionRoles == null) throw new InvalidOperationException();

            // Authorize
            if (permissionRoles.Count > 0 && permissionRoles.Any(user.IsInRole) == false)//权限带有的角色是否存在于用户所属的角色中
            {
                return false;
            }
            if (permissionRoles.Count == 0 && string.IsNullOrEmpty(permissionName) == false) return false;

            // Return
            return true;
        }
    }
}